<?php
namespace PsiFramework\Classes\Util\Object;

import("Classes.Model.ModelInterface.IPrimitiveObject");
import("Classes.Util.Database.Query.SqlType");

use \PsiFramework\Classes\Util\Database\Query\SqlType;
use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The CollectionElement class is used to Collection Elements
 *
 * @package Util.Object
 */
abstract class CollectionElement implements IPrimitiveObject
{

    protected /*string*/            $_value ;
    protected /*Collection*/        $_children ;
    protected /*CollectionElement*/ $_parent ;
    protected /*CollectionElement*/ $_previousSibling ;
    protected /*CollectionElement*/ $_nextSibling ;

    public function __construct(
        /*string*/ $value=null,
        Collection $children=null
    )
    {
        $this->_value = $value ;
        $this->_children = $children ;

        $this->_parent = null ;
        $this->_previousSibling = null ;
        $this->_nextSibling = null ;
    }

    public function getValue()
    {
        return $this->_value ;
    }

    public function getChildren()
    {
        return $this->_children ;
    }

    public function getParent()
    {
        return $this->_parent ;
    }

    public function getPreviousSibling()
    {
        return $this->_previousSibling ;
    }

    public function getNextSibling()
    {
        return $this->_nextSibling ;
    }

    public function setValue(/*string*/ $value)
    {
        $this->_value = $value ;
    }

    public function setChildren(
        Collection $children,
        CollectionElement $parent=null
    )
    {
        $this->_children = $children ;
        if (!is_null($parent)) {
            foreach ($this->_children->getElements() as $element) {
                $element->parent = $parent ;
            }
        }
    }

    public function appendChild(CollectionElement $element)
    {
        $element->setParent($this);
        $this->_children->addNode($element);
    }

    public function setParent(CollectionElement $element)
    {
        $this->_parent = $element ;
    }

    public function setPreviousSibling(CollectionElement $element)
    {
        $this->_previousSibling = $element ;
    }

    public function setNextSibling(CollectionElement $element)
    {
        $this->_nextSibling = $element ;
    }

    public function serialize(/*boolean*/ $asText=true)
    {
        $element = new \stdClass();
        $element->value = $this->_value ;
        $children = null ;
        if (!is_null($this->_children)) {
            $children = $this->_children->serialize(false);
        }
        if (!is_null($children)) {
            $element->children = $children ;
        }

        if ($asText) {
            return json_encode($element);
        } else {
            return $element ;
        }
    }

    public function toString()
    {
        return $this->_value ;
    }

    public static function getSqlType()
    {
        return SqlType::$text ;
    }

}
